//----------------------------------------------------------------------------------------------
//	Filename:	SegmentsGraph.h
//	Author:		Sandro Spina
//	Date:		27/01/2013
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
#pragma once
#include "UniqueId.h"
#include <map>
#include <stack>
#include <Geometry\Vector3.h>

namespace Illumina
{
	namespace Core
	{
		class ObjStructureGraph
		{
		public:

			::UniqueID * nodeID;

			enum shape {line,plane,sphere,complex,compound};

			//More actions can be added here eventually ...
			enum action {add_direction,transition_count};

			enum attributes {
				angle,			//angle between nodes (shapes)
				dot				//dot product between nodes (shapes)
			};

			enum nodetype {
				accepting,
				rejecting,
				unknown
			};

			//Node IDs are the same as corresponding surface segment ids.
			struct EdgeStats
			{
				std::string label;		
				int strength;		
				float dot;
				float epsilon;
				std::vector<action> actions;
			};

			struct NodeStats
			{				 
				std::string label;
				int point_count;
				//int fork_condition; // 0=OR, 1=AND
				shape shape;
				nodetype type;		
				Vector3 orientation;
			};

			struct Node
			{
				int id;	
				int used;
				NodeStats* stats;
				std::vector<std::pair<EdgeStats*, Node*> *> * edges;		
			};

			std::map<int, Node*> * nodes;
			std::map<int, Node*>::iterator nodesIterator;

			std::stack<std::vector<int>*> * ConsumedStates;
	
			Illumina::Core::List<Node*> * DisjointStructureGraphs;

			std::map<std::string, int> * DirectionsTravelledFromTrainingSet;

			int initial_node_id;	

			ObjStructureGraph();
			void SetInitialNodeId(int pId);
			int GetInitialNodeId(void);

			//Create and populate a new node to represent a surface segment. Add to nodes map.
			void AddNode(Node * &p_node);
	
			std::map<int, Node*> * GetNodes();
		};
	}
}